import java.lang.reflect.Method;

/**
 *  反射：
 * java反射是在运行状态中，对于java任意一个类，都能够知道这个类的所有属性
 * 和方法；对于任意一个对象，都能够调用它的任意一个方法和属性；或者说是将类
 * 的各个组成部分封装为其他对象。
 *
 *  作用：
 * 在java中，只要给定类的名字，就可以通过反射机制来获得类的所有信息。这种
 * 动态获取的信息以及动态调用对象的方法的功能称之为java语言的反射机制。
 *
 *  优点：
 *  能够运行时动态获取类的实例，提高灵活性
 *
 *  缺点：
 *  使用反射性能较低，反射相当于一系列解释操作，通知JVM要做的事情，这类操作
 *  总是慢于直接执行java代码。
 *
 */
public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        Student stu = new Student();
        long start = System.currentTimeMillis();
        for (int i = 0; i <=100000000; i++) {
            stu.eat();
        }
        long end = System.currentTimeMillis();
        System.out.println("普通方式创建对象耗时:"+(end-start));

        long start1 = System.currentTimeMillis();
        Class stu2 = Class.forName("Student");
        Object o = stu2.newInstance();
        Method md = stu2.getMethod("eat");
        for (int i = 0; i <= 100000000; i++) {
            md.invoke(o);
        }
        long end1 = System.currentTimeMillis();
        System.out.println("反射方法创建对象耗时:"+(end1-start1));
        /*
        AccessibleObject类是Field，Method和Constructor对象的基类。
        setAccessible()作用是启动和禁用安全访问检查的开关。true的值表
        示反射对象应该在使用时抑制Java语言访问检查， false的值表示反映
        对象执行Java语言访问检查。
         */
        long start2 = System.currentTimeMillis();
        md.setAccessible(true);
        for (int i = 0; i <= 100000000; i++) {
            md.invoke(o);
        }
        long end2 = System.currentTimeMillis();
        /*
        解决方案：
        1、通过setAccessible(true)关闭JDK的安全检查来提升反射速度；
        2、多次创建一个类的实例时，有缓存会快很多
        3、ReflectASM工具类，通过字节码生成的方式加快反射速度
          相对不安全，破坏了封装性（因为通过反射可以获得私有方法和属性)
         */
        System.out.println("关闭安全访问检查能够一定程度上优化反射机制");
        System.out.println("反射方式优化创建对象耗时："+(end2-start2));
    }
}













































